package com.example.codereview;

import com.example.codereview.git.GitService;
import com.example.codereview.git.model.*;
import com.example.codereview.git.swing.ReviewTreePanel;
import com.example.codereview.util.DateUtils;
import com.example.codereview.util.JOptionPaneUtils;
import com.example.codereview.util.ObjectUtils;
import com.example.codereview.util.ThreadExecutors;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBPanel;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBTextField;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

public class GitView extends SimpleToolWindowPanel implements MouseListener, KeyListener {

    private JBTextField authorField;

    private JBTextField startDateField;

    private JButton button;

    private JBPanel headPanel;

    private ReviewTreePanel bodyPanel;

    private JBPanel detailPanel;

    private JBScrollPane scrollPane;

    private boolean searchActive = false;

    private Project project;

    private Date startDate;
    private String author;

    private VirtualFile nowFile;

    private JBScrollPane bodyScrollPane;

    private ProjectQuery query = new ProjectQuery();

    private GitService gitService = GitService.getInstance();

    public GitView(Project project){
        super(true,true);
        this.project = project;
        // 获取模块管理器
        this.setLayout(new BorderLayout());
        this.headPanel = new JBPanel();
        FlowLayout flowLayout = new FlowLayout();
        flowLayout.setAlignment(FlowLayout.LEFT);
        this.headPanel.setLayout(flowLayout);

        //文本框
        this.authorField = new JBTextField();
        this.authorField.setSize(120,25);
        this.authorField.setColumns(10);
        this.authorField.setText("author");
        this.authorField.setOpaque(true);
        this.authorField.setBackground(JBColor.background());
        this.headPanel.add(authorField);

        this.startDateField = new JBTextField();
        this.startDateField.setSize(120,25);
        this.startDateField.setColumns(10);
        this.startDateField.setOpaque(true);
        this.startDateField.setBackground(JBColor.background());
        this.startDateField.setText(DateUtils.dateToStr(DateUtils.getLastDay(new Date(),7)));
        this.headPanel.add(startDateField);

        this.button = new JButton();
        this.button.setSize(60,25);
        this.button.setText("search");
        this.button.setOpaque(true);
        this.button.setBackground(JBColor.background());
        this.headPanel.add(this.button);

        this.add(headPanel,BorderLayout.NORTH);


        //bodyPanel
        initBodyPanel();

        detailPanel = new JBPanel();
        JBScrollPane detailScroll = new JBScrollPane(detailPanel);
        this.detailPanel.setVisible(true);

        this.authorField.addKeyListener(this);
        this.startDateField.addKeyListener(this);
        this.button.addMouseListener(this);

        Splitter splitter = new Splitter(true); // false 表示水平分割
        splitter.setFirstComponent(bodyScrollPane);
        splitter.setSecondComponent(detailScroll);
        splitter.setDividerWidth(1);
        splitter.setProportion(0.6F);

//        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
//                true, this.bodyScrollPane, detailScroll);
//        splitPane.setDividerSize(1);
//        splitPane.setForeground(JBColor.LIGHT_GRAY);
//        splitPane.setDividerLocation(500);
        this.add(splitter,BorderLayout.CENTER);
        this.setVisible(true);
    }


    public void refreshBodyPanel(){
        if(searchActive){
            return;
        }
        searchActive = true;
        this.bodyPanel.setVisible(false);
        if(!ObjectUtils.isEmpty(scrollPane)){
            this.bodyPanel.remove(scrollPane);
        }
        this.bodyPanel.setVisible(true);
        JTree tree = loadJTree();
        if(tree == null){
            searchActive = false;
            return;
        }
        // 确保组件是透明的，以便背景颜色能显示出来
        tree.setOpaque(true);
        tree.setBorder(null);
        scrollPane = new JBScrollPane(tree);
        scrollPane.setOpaque(true);
        // 设置视口背景色同样一致
//        scrollPane.getViewport().setBackground(JBColor.background());

//        scrollPane.setPreferredSize(this.getSize());
        this.bodyPanel.setContent(scrollPane);
        this.scrollPane.setVisible(true);
        this.bodyPanel.setVisible(true);
        this.bodyPanel.stopWait();
        tree.addMouseListener(this);
        this.revalidate();
        searchActive = false;
    }

    private JTree loadJTree(){
        //代码信息
        String text = this.authorField.getText();
        String dateStr = this.startDateField.getText();
        if(ObjectUtils.isEmpty(dateStr)){
            JOptionPaneUtils.warn("请输入日期");
            return null;
        }
        ThreadExecutors threadExecutors = new ThreadExecutors();
        CompletableFuture aysnc = threadExecutors.aysnc(() -> {
            try {
                Date date = DateUtils.strToDate(dateStr);
                query.setStartDate(date);
                this.startDate = date;
            } catch (Exception e) {
                JOptionPaneUtils.warn("请输入正确的日期");
                this.bodyPanel.stopWait();
                return null;
            }
            try {
                query.setAuthor(text);
                this.author = query.getAuthor();
                List<ReviewProjectResp> resps = gitService.getProject(query, this.project);
                //组装树
                TreeComponent node = new TreeComponent(this.project.getName());
                node.setData(new ReviewProjectResp());
                createTreeNode(node, resps);
                JTree tree = new JTree(node);
                tree.setFont(new Font(null,Font.PLAIN,14));
                tree.setCellRenderer(new DefaultTreeCellRenderer() {
                    @Override
                    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
                        super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
                        // 获取文件类型
                        String s = String.valueOf(value);
                        if(s.contains(".")) {
                            String prefix = s.substring(s.lastIndexOf(".")+1);
                            FileType fileType = FileTypeRegistry.getInstance().getFileTypeByExtension(prefix);
                            // 获取图标
                            if (!ObjectUtils.isEmpty(fileType) && !ObjectUtils.isEmpty(fileType.getIcon())) {
                                setIcon(fileType.getIcon());
                            }
                        }
                        ModuleManager moduleManager = ModuleManager.getInstance(project);
                        // 获取项目关联的 modules
                        Module[] modules = moduleManager.getModules();
                        for(Module module : modules){
                            if(s.equals(module.getName())){
                                Icon icon = ModuleType.get(module).getIcon();
                                if (!ObjectUtils.isEmpty(icon)) {
                                    setIcon(icon);
                                }
                                break;
                            }
                        }
                        return this;
                    }
                });
                //监听
                tree.addTreeSelectionListener(new TreeSelectionListener() {//添加listener
                    @Override
                    public void valueChanged(TreeSelectionEvent e) {
                        Object bean = ((TreeComponent) e.getNewLeadSelectionPath().getLastPathComponent()).getData();
                        if (bean instanceof ReviewProjectFile) {
                            ReviewProjectFile projectFile = (ReviewProjectFile) bean;
                            VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(projectFile.getPath());

                            FileEditorManager editorManager = FileEditorManager.getInstance(project);
                            if(!ObjectUtils.isEmpty(virtualFile)) {
                                nowFile = virtualFile;
                                editorManager.openFile(virtualFile, false);
                                List<ProjectFileCode> codes = projectFile.getCodes();
                                initJLabelDetail(codes);
                            }
                        }
                    }
                });
                this.bodyPanel.stopWait();
                return tree;
            }catch (Exception e){
                this.bodyPanel.stopWait();
                return null;
            }
        });
        this.bodyPanel.startWait();
        return (JTree) threadExecutors.get(aysnc);
    }

    private void initJLabelDetail(List<ProjectFileCode> codes){
        if(this.startDate == null){
            return;
        }
        List<String> labelValues = new ArrayList<>();
        int firstNumber = 0;
        int number = 0;
        for(ProjectFileCode code : codes){
            Date lastChangeTime = code.getLastChangeTime();
            number = code.getNumber();
            if(lastChangeTime != null && lastChangeTime.after(startDate) && author != null && author.equals(code.getAuthor().getUsername())){
                if(firstNumber == 0){
                    firstNumber = number;
                }
            }else{
                if(firstNumber > 0){
                    labelValues.add(firstNumber+"-"+(number-1));
                }
                firstNumber = 0;
            }
        }
        if(firstNumber > 0){
            labelValues.add(firstNumber+"-"+(number));
        }

        if(labelValues.size() == 0){
            return;
        }
        int rows = 10;
        if(labelValues.size() > 10){
            rows = labelValues.size();
        }
        GridLayout gridLayout = new GridLayout(rows,1);
        detailPanel.setLayout(gridLayout);
        detailPanel.removeAll();
        for(int i =0 ; i< labelValues.size(); i++){
            String value = labelValues.get(i);
            JBLabel label = new JBLabel(value);
            label.setName(value);
            label.setFont(new Font(null,Font.PLAIN,16));
            label.setForeground(JBColor.BLUE);
            this.detailPanel.add(label);
            label.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if(nowFile == null){
                        return;
                    }
                    String name = label.getName();
                    String[] split = name.split("-");
                    String start = split[0];
                    String end = split[1];
                    int lineStartNum = Integer.parseInt(start);
                    if(lineStartNum > 0){
                        lineStartNum = lineStartNum -1;
                    }
                    int lineEndNum = Integer.parseInt(end);
                    if(lineEndNum > 0){
                        lineEndNum = lineEndNum - 1;
                    }
                    FileEditorManager editorManager = FileEditorManager.getInstance(project);
                    TextEditor textEditor = (TextEditor) editorManager.getSelectedEditor(nowFile);
                    if (textEditor != null) {
                        Editor editor = textEditor.getEditor();
                        editor.getScrollingModel().scrollTo(editor.offsetToLogicalPosition(editor.getDocument().getLineStartOffset(lineStartNum - 1)), ScrollType.CENTER_UP);

                        int lineStart = editor.getDocument().getLineStartOffset(lineStartNum);
                        int lineEnd = editor.getDocument().getLineEndOffset(lineEndNum);
                        editor.getSelectionModel().setSelection(lineStart, lineEnd);
                    }
                }
            });
        }
        detailPanel.revalidate();
        detailPanel.repaint();

    }



    private void createTreeNode(TreeComponent component, List<ReviewProjectResp> projectResps){
        if(ObjectUtils.isEmpty(projectResps)){
            return;
        }
        for(ReviewProjectResp resp : projectResps){
            TreeComponent node = new TreeComponent(resp.getName());
            node.setData(resp);
            createTreeFileNode(node,resp.getFiles());
            component.add(node);
        }
    }

    private void createTreeFileNode(TreeComponent component, List<ReviewProjectFile> files){
        if(ObjectUtils.isEmpty(files)){
            return;
        }
        for(ReviewProjectFile file : files){
            TreeComponent node = new TreeComponent(file.getFileName());
            node.setData(file);
            createTreeFileNode(node,file.getFiles());
            component.add(node);
        }
    }


    private void initBodyPanel(){
        this.bodyPanel = new ReviewTreePanel();
        BorderLayout layout = new BorderLayout();
        this.bodyPanel.setLayout(layout);
        this.bodyPanel.setVisible(true);
        this.bodyScrollPane = new JBScrollPane(this.bodyPanel);
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if(10 == keyCode){
            Object source = e.getSource();
            if(source instanceof JTextField) {
                new Thread(this::refreshBodyPanel).start();
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        Object source = e.getSource();
        if(source == this.button){
            new Thread(this::refreshBodyPanel).start();

        }
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}
